home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_075 / comm / wxmdmsend.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  5KB  |  237 lines

  1.  
  2. /* Comm WXMODEM send routines */
  3.  
  4. #define  WXMDMSEND 1
  5.  
  6. #include "globals.h"
  7. #include <fcntl.h>
  8.  
  9. extern void      emit_tx_protocol(), emit_vw(), emits_rx();
  10. extern void      send_proto(), do_crc();
  11. extern int       read_proto();
  12.  
  13. static int naks, errsect;
  14. static ULONG bytes;
  15. static UBYTE sent, acked;
  16. static ULONG  lastacked, nak_blk, ack_blk;
  17.  
  18. WXMODEM_Send_File(file)
  19. UBYTE *file;
  20. {
  21.     ULONG temp;
  22.     int status, errcnt, eof = FALSE;
  23.     int ch;
  24.  
  25.     naks = errsect = bytes = lastacked = acked = sent = errcnt = 0;
  26.  
  27.    while(!abort && (errcnt < RETRYMAX) )
  28.    {
  29.       do {
  30. top:
  31.             sprintf(sbuff,"File: %s  bytes= %ld  naks= %d [ %d ]\r",
  32.                 file, bytes, naks, errsect);
  33.             status_line(0,sbuff);
  34.  
  35.             if((status = fillbuf()) == ERROR)
  36.             {
  37.                abortsend();
  38.                return FALSE;
  39.             }
  40.             if(status == FALSE)
  41.                eof = TRUE;
  42.             else
  43.             {
  44.                 if(sendwsector() == ABORT)
  45.                 {
  46.                   abortsend();
  47.                   return FALSE;
  48.                 }
  49.                 sent = sector & 3;
  50.                 sector++;
  51.             }
  52.             if((ch = getresponse()) != FALSE)
  53.             {
  54.                if(ch == NAK)
  55.                {
  56.                   errcnt++; naks++;
  57.                   emits_rx("  NAK received\n");
  58.  
  59.                   nak_blk += 4;
  60.                   temp = (nak_blk - (lastacked & 3)) & 3;
  61.                   sector = (unsigned)(lastacked + temp);
  62.                   temp = (ULONG)SECSIZ * (ULONG)(sector - 1);
  63.                   if(lseek(fd,temp,0) == -1)
  64.                   {
  65.                      emits_rx("  File position error!\n");
  66.                      abortsend();
  67.                      return FALSE;
  68.                   }
  69.                   errsect = sector;
  70.                   goto top;
  71.                }
  72.                else if(ch == ACK)
  73.                {
  74.                   errcnt = 0;
  75.                   ack_blk += 4;
  76.                   temp = (ack_blk - (lastacked & 3)) & 3;
  77.                   if(temp == 0) temp = 4;
  78.                   lastacked += temp;
  79.  
  80.                   bytes += (SECSIZ * temp);
  81.                }
  82.                else if(ch == CAN)
  83.                {
  84.                   send_proto(ACK);
  85.                   emits_rx("  Received cancel request\n");
  86.                   close(fd);
  87.                   return TRUE;
  88.                }
  89.             }
  90. /*
  91.             sprintf(sbuff,"File: %s  bytes= %ld  naks= %d [ %d ]\r",
  92.                 file, bytes, naks, errsect);
  93.             status_line(0,sbuff);
  94. */
  95.       } while ( acked != sent );
  96.       if(eof)
  97.       {
  98.          endfile(); close(fd);
  99.          return TRUE;
  100.       }
  101.       errcnt++;
  102.       lseek(fd,(long)(-SECSIZ),1);
  103.       sector--;
  104.       Delay(250L);
  105.    }
  106.    abortsend();
  107.    return FALSE;
  108. }
  109.  
  110. /**************************************
  111. sendwsector() transmits a single sector
  112. ***************************************/
  113. sendwsector(  )
  114. {
  115.    int i;
  116.    cancel = FALSE;
  117.  
  118.    Process_window_event();
  119.    if( cancel || abort )
  120.        return ABORT;
  121.  
  122.    sprintf(sbuff,"\rTransmitting block %d",sector);
  123.    emits_rx(sbuff);
  124.    send_proto(SYN); send_proto(SYN); send_proto(SYN);
  125.  
  126.    send_wproto( SOH );          /* start of block */
  127.    send_wproto( sector );       /* sector number  */
  128.    send_wproto( ~sector );      /* compliment of sector number */
  129.    crc = 0;                     /* clear CRC */
  130.  
  131.    for( i = 0 ; i < SECSIZ ; i++ )
  132.    {
  133.       if(xbuffer[ i ] == '\n' && asciiflg)
  134.          xbuffer[ i ] = '\r';
  135.       wsendchar(xbuffer[ i ]);
  136.       do_crc( xbuffer[ i ] );
  137.       if(viewflg)
  138.         emit_vw( xbuffer[ i ] );
  139.    }
  140.  
  141.    do_crc(0); do_crc(0);     /* cycle CRC generator */
  142.    wsendchar( crc >> 8 );    /* High byte */
  143.    wsendchar( crc );         /* Low byte */
  144. }
  145.  
  146. send_wproto(ch)
  147. UBYTE ch;
  148. {
  149.    emit_tx_protocol(ch);
  150.    wsendchar(ch);
  151. }
  152.  
  153. wsendchar(ch)
  154. UBYTE ch;
  155. {
  156.    switch(ch)
  157.    {
  158.       case SYN: case DLE:
  159.       case XON: case XOFF:
  160.                              sendchar(DLE);
  161.                              sendchar( ch ^ 64);
  162.                              break;
  163.       default:               sendchar(ch);
  164.    }
  165. }
  166.  
  167. getresponse()
  168. {
  169.    int ch;
  170.  
  171.    while(check_line())
  172.    {
  173.      ch = read_proto(10,0);
  174.      switch(ch)
  175.      {
  176.         case XOFF:
  177.             do {
  178.                   ch = read_proto(10,0);
  179.             } while( ch != XON && ch != TIMEOUT);
  180.             return FALSE;
  181.         case XON:
  182.             return FALSE;
  183.         case ACK:
  184.             ch = read_proto(10,0);
  185.             if(ch & ~3) return FALSE;
  186.             ack_blk = acked = ch;
  187.             return ACK;
  188.         case NAK:
  189.             ch = read_proto(10,0);
  190.             if(ch & ~3) return FALSE;
  191.             nak_blk = (ch & 3);
  192.             return NAK;
  193.         case CAN:
  194.             ch = read_proto(10,0);
  195.             if(ch == CAN)
  196.                return CAN;
  197.      }
  198.    }
  199.    return FALSE;
  200. }
  201.  
  202. endfile()
  203. {
  204.    int ch, errs = 0;
  205.  
  206.    do {
  207.          send_proto(EOT);
  208.          ch = read_proto(5,0);
  209.          if(ch == TIMEOUT) errs++;
  210.    } while(ch != ACK && errs < 3);
  211.  
  212. }
  213.  
  214. abortsend()
  215. {
  216.    int ch, errs = 0;
  217.  
  218.    emits_rx("\nAborting transfer\n");
  219.    send_proto(CAN); send_proto(CAN);
  220.  
  221.    do {
  222.          ch = read_proto(4);
  223.          if(ch == CAN)
  224.          {
  225.             if(read_proto(4) == CAN)
  226.                break;
  227.          }
  228.          if(ch == TIMEOUT)
  229.          {
  230.             send_proto(CAN); send_proto(CAN);
  231.             errs++;
  232.          }
  233.    } while (errs < 3);
  234.    send_proto(ACK);
  235. }
  236.  
  237.